package com.iwuyc.tools.commons.structs.collections;

import com.iwuyc.tools.commons.util.collection.ArrayUtil;
import lombok.extern.slf4j.Slf4j;

import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

/**
 * This class represents a specialized implementation of the HashMap class, specifically designed for storing key-value pairs
 * where the keys are of type String and the values are of any type specified by the generic parameter K.
 */
@Slf4j
public class StringHashMap<K> extends HashMap<String, K> {
    private static final long serialVersionUID = 1L;

    /**
     * Constructs a new empty StringHashMap
     */
    public StringHashMap() {
        super();
    }

    /**
     * Constructs a new StringHashMap with the specified initial capacity
     *
     * @param initialCapacity the initial capacity of the StringHashMap
     */
    public StringHashMap(int initialCapacity) {
        super(initialCapacity);
    }

    /**
     * Constructs a new StringHashMap using the elements from the specified source map
     *
     * @param sourceMap the source map whose elements will be added to this StringHashMap
     */
    public StringHashMap(Map<String, ? extends K> sourceMap) {
        super(sourceMap);
    }

    /**
     * Separates the properties of this StringHashMap by prefixes and returns a map of maps.
     *
     * @param prefixes the prefixes to be used for separating the properties
     * @return a map of maps containing the separated properties, where the keys are the prefixes and the values are maps containing the properties without the prefix
     */
    public Map<String, Map<String, K>> separatePropertiesByPrefix(String... prefixes) {
        // 判断是否开启debug模式
        if (log.isDebugEnabled()) {
            log.debug("prefixes: {}", Arrays.toString(prefixes));
        }
        // 如果prefixes为空，返回空Map
        if (ArrayUtil.isEmpty(prefixes)) {
            return Collections.emptyMap();
        }
        // 创建一个Map，用于存放拆分后的属性
        final Map<String, Map<String, K>> separatedProperties = new HashMap<>();

        // 遍历this，获取每一个属性
        for (Map.Entry<String, K> entry : this.entrySet()) {
            String key = entry.getKey();
            K value = entry.getValue();
            String prefix = null;

            // 遍历prefixes，找到与key匹配的prefix
            for (String item : prefixes) {
                if (key.startsWith(item)) {
                    prefix = item;
                    break;
                }
            }
            // 如果没有找到prefix，跳过本次循环
            if (null == prefix) {
                log.debug("prefix can't found.");
                continue;
            }
            // 将key中的prefix移除
            final String keyWithoutPrefix = key.substring(prefix.length());
            // 将prefix作为key，将value作为value，存入separatedProperties
            final Map<String, K> separateContainer = separatedProperties.computeIfAbsent(prefix, k -> new HashMap<>());
            separateContainer.put(keyWithoutPrefix, value);
        }

        return separatedProperties;
    }

    /**
     * Creates an empty StringHashMap.
     *
     * @param <K> the type of values in the StringHashMap
     * @return an empty StringHashMap
     */
    public static <K> StringHashMap<K> empty() {
        return new StringHashMap<>();
    }

}
